<?php
declare(strict_types=1);

namespace NanQi\Hope;

use Hyperf\AsyncQueue\JobInterface;
use Faker\Factory;
use Faker\Generator;
use Hyperf\AsyncQueue\Driver\DriverFactory;
use Hyperf\Cache\CacheManager;
use Hyperf\Cache\Driver\CoroutineMemoryDriver;
use Hyperf\Cache\Driver\DriverInterface;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\Redis\RedisFactory;
use Hyperf\Redis\RedisProxy;
use Hyperf\Server\ServerFactory;
use NanQi\Hope\Base\BaseEvent;
use NanQi\Hope\Service\JwtService;
use NanQi\Hope\Traits\ResponseFormatTrait;
use Psr\EventDispatcher\EventDispatcherInterface;
use Swoole\Server;


/**
 * Class Hope
 * @package NanQi\Hope
 * @method static getRedis($name) : RedisProxy
 * @method static getRedisBusiness() : RedisProxy
 * @method static getReq() : RequestInterface
 * @method static getRes() : ResponseInterface
 * @method static getFaker() : Generator
 * @method static isProduct() : bool
 * @method static getLog() : StdoutLoggerInterface
 * @method static getAuthId() : int
 * @method static isLogin() : bool
 * @method static getArrayCache() : DriverInterface
 * @method static getServer() : Server
 * @method static mq(JobInterface $job, int $delay = 0, string $channel = 'default') : bool
 */
final class Hope
{
    use Helper;

    private static $instance;

    public static function __callStatic($name, $arguments)
    {
        if (!self::$instance) {
            self::$instance = new Hope();
        }

        return self::$instance->$name(...$arguments);
    }

    /**
     * 缩短ID长度
     * @param int $id
     * @param string $alphabet
     * @return string
     */
    public static function shorten(int $id, string $alphabet='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-')
    {
        $base = strlen($alphabet);
        $short = '';
        while($id) {
            $id = ($id-($r=$id%$base))/$base;
            $short = $alphabet[$r] . $short;
        }
        return $short;
    }

    /**
     * 加长ID长度
     * @deprecated 不推荐使用，需可逆ID不存储短ID
     * @param string $m
     * @param string $alphabet
     * @return string
     */
    public static function longen(string $m, string $alphabet='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-') {
        $hex2 = '';
        for($i = 0, $l = strlen($alphabet); $i < $l; $i++) {
            $KeyCode[] = $alphabet[$i];
        }
        $KeyCode = array_flip($KeyCode);

        for($i = 0, $l = strlen($m); $i < $l; $i++) {
            $one = $m[$i];
            $hex2 .= str_pad(decbin($KeyCode[$one]), 6, '0', STR_PAD_LEFT);
        }
        $return = bindec($hex2);

        return $return;
    }

    /**
     * 指定精度格式化数字
     * @param string $num
     * @param int $scale
     * @return string
     */
    public static function formatNumber(string $num, int $scale = 8) : string {
        $num = round($num, $scale + 1);
        if(false !== stripos("$num", "e")){
            $a = explode("e",strtolower("$num"));
            return bcmul($a[0], bcpow("10", $a[1], $scale), $scale);
        } else {
            return bcadd("$num", '0', $scale);
        }
    }
}


